home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Whiteline: delta
/
whiteline CD Series - delta.iso
/
tex
/
tools
/
dvi_300b
/
treiber
/
dvinadel.lzh
/
dvinadel
/
nadel.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-20
|
34KB
|
1,041 lines
/*
Nadel-Druckertreiber für DVI
Version 1.2
Copyright (c) Markus Kohm, 1995
Diese Treiberbasisdatei kommt mit Nadeldruckern und
Tintenspritzern, die wie Nadeldrucker angesteuert werden,
von 8 bis 48 Nadeln (bzw. Düsen) zurecht.
Es wird lediglich eine Ansteuerungsdefinitionsdatei benötigt.
Ein Beispiel dafür liefert LQ850.C.
Der Ausdruck wird über das Modul prt_base erledigt.
Es wird MiNTLIB PL 46 benötigt.
*/
#ifndef NADEL_C
#define NADEL_C
#ifndef PRT_BASE_H
# error "Diese Datei immer nur per #include verwenden (siehe dvi_prt.c)!"
#endif
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <mintbind.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include "dvi_low.h"
#ifndef SHMGETBLK
# define SHMGETBLK (0x4d00)
#endif
#if !defined( PORTRAIT ) && !defined( LANDSCAPE )
# define PORTRAIT
# define LANDSCAPE
#endif
char EVERYSECONDBIT[128] = {
0x0, 0x1, 0x0, 0x1, 0x2, 0x3, 0x2, 0x3,
0x0, 0x1, 0x0, 0x1, 0x2, 0x3, 0x2, 0x3,
0x4, 0x5, 0x4, 0x5, 0x6, 0x7, 0x6, 0x7,
0x4, 0x5, 0x4, 0x5, 0x6, 0x7, 0x6, 0x7,
0x0, 0x1, 0x0, 0x1, 0x2, 0x3, 0x2, 0x3,
0x0, 0x1, 0x0, 0x1, 0x2, 0x3, 0x2, 0x3,
0x4, 0x5, 0x4, 0x5, 0x6, 0x7, 0x6, 0x7,
0x4, 0x5, 0x4, 0x5, 0x6, 0x7, 0x6, 0x7,
0x8, 0x9, 0x8, 0x9, 0xa, 0xb, 0xa, 0xb,
0x8, 0x9, 0x8, 0x9, 0xa, 0xb, 0xa, 0xb,
0xc, 0xd, 0xc, 0xd, 0xe, 0xf, 0xe, 0xf,
0xc, 0xd, 0xc, 0xd, 0xe, 0xf, 0xe, 0xf,
0x8, 0x9, 0x8, 0x9, 0xa, 0xb, 0xa, 0xb,
0x8, 0x9, 0x8, 0x9, 0xa, 0xb, 0xa, 0xb,
0xc, 0xd, 0xc, 0xd, 0xe, 0xf, 0xe, 0xf,
0xc, 0xd, 0xc, 0xd, 0xe, 0xf, 0xe, 0xf
};
#define EVENBITS(x) EVERYSECONDBIT[x/2]
#define ODDBITS(x) EVERYSECONDBIT[x&127]
#define WHICHNORMAL(n,x) x
char DOUBLEBITS[16] = {
0x00, 0x03, 0x0c, 0x0f,
0x30, 0x33, 0x3c, 0x3f,
0xc0, 0xc3, 0xcc, 0xcf,
0xf0, 0xf3, 0xfc, 0xff };
#define DOUBLEFIRST(x) (DOUBLEBITS[((x) >> 4) & 0x0f])
#define DOUBLESECOND(x) (DOUBLEBITS[(x) & 0x0f])
#define WHICHDOUBLE(n,x) (((n) == 0)? DOUBLEFIRST(x) : DOUBLESECOND(x))
char TRIPLEFIRSTBITS[8] = {
0x00, 0x03, 0x1c, 0x1f,
0xe0, 0xe3, 0xfc, 0xff };
char TRIPLESECONDBITS[16] = {
0x00, 0x01, 0x0e, 0x0f,
0x70, 0x71, 0x7e, 0x7f,
0x80, 0x81, 0x8e, 0x8f,
0xf0, 0xf1, 0xfe, 0xff };
#define TRIPLEFIRST(x) TRIPLEFIRSTBITS[(x >> 5) & 0x07]
#define TRIPLESECOND(x) TRIPLESECONDBITS[(x >> 2) & 0x0f]
#define TRIPLETHIRD(x) ((TRIPLEFIRSTBITS[x & 0x07] << 1) |\
TRIPLEFIRSTBITS[x & 0x07])
#define WHICHTRIPLE(n,x) ((n == 0)? TRIPLEFIRST(x) : \
((n == 1)? TRIPLESECOND(x) : TRIPLETHIRD(x)))
#define QUADFIRST(x) DOUBLEFIRST(DOUBLEFIRST(x))
#define QUADSECOND(x) DOUBLESECOND(DOUBLEFIRST(x))
#define QUADTHIRD(x) DOUBLEFIRST(DOUBLESECOND(x))
#define QUADFORTH(x) DOUBLESECOND(DOUBLESECOND(x))
#define WHICHQUAD(n,x) ((n == 0)? QUADFIRST(x) : \
((n == 1)? QUADSECOND(x) : \
((n == 2)? QUADTHIRD(x) : QUADFORTH(x))))
#define WHICHBITS(m,r,x) ((m <= EMUNORMAL)? WHICHNORMAL(r,x) : \
((m == EMUHALF)? WHICHDOUBLE(r,x) : \
((m == EMUTRIPLE)? WHICHTRIPLE(r,x) : \
WHICHQUAD(r,x))))
extern int drucke( char *memory,
long offset, long width, long height,
long hdpi, long vdpi, int flag,
int landscape, const char *options );
#ifdef LANDSCAPE
extern int druck_landscape( char *memory,
long xoffset, long yoffset,
long width, long height,
PAGESIZE *pg,
PRTHMODE *phm, PRTVMODE *pvm,
boolean onlypart );
#endif
#ifdef PORTRAIT
extern int druck_portrait( char *memory,
long xoffset, long yoffset,
long width, long height,
PAGESIZE *pg,
PRTHMODE *phm, PRTVMODE *pvm,
boolean onlypart );
#endif
extern int workoptions( const char *optionen,
long *offset, long *width, long *height,
long *hdpi, long *vdpi, int *landscape );
int main( int argc, const char *argv[] ) {
const char *shm_name, *optionen;
char *memory;
long i, shm, offset, w, h, xdpi, ydpi;
int landscape, ret, flag;
if ( argc < 6 ) {
Cconws( "Zuwenig Argumente!\r\n" );
Cconws( "Richtig: shared_mem_file -Offset -pl weite hoehe hdpi vdpi [file] [-\"Optionen]\r\n" );
Cconws( "-pl: p = 1: nur ein Teil, sonst: mehrere Teile\r\n" );
Cconws( " l = l: landscape, sonst: portrait\r\n" );
return -1;
}
Psignal( SIGUSR1, (long)SIG_IGN );
/* Diese Routine mit Parameter versehen! */
/* Es wird mit Shared Memory gearbeitet */
/* Wenn der erste Buchstabe eine Zahl ist, */
/* dann wird diese als Adresse angenommen */
shm_name = argv[1];
if( isdigit( *shm_name ) ) {
if ( ( i = atol( shm_name ) ) <= 0 )
return -ENOENT;
memory = (char *)i;
shm_name = NULL;
} else {
if ( ( shm = Fopen( shm_name, O_RDONLY ) ) < 0 )
return (int)shm;
else if ( ( i = Fcntl( (int)shm, 0L, SHMGETBLK ) ) < 0 )
return (int)i; /* Fehler melden */
memory = (char *)i;
}
/* Es folgt das Offset */
offset = -atol( argv[2] ); /* bisheriges offset */
flag = 2; /* Inhalt */
if( argv[3][1] == '1' )
flag |= 4;
if( offset==0 )
flag |= 1;
landscape = ( argv[3][2] == 'l' );
w = atol( argv[4] );
h = atol( argv[5] );
xdpi = atol( argv[6] );
ydpi = atol( argv[7] );
optionen = NULL;
if ( argc > 8 ) {
if( argv[8][0]=='-' && argv[8][1]=='\"' ) {
optionen = argv[8]+2;
if ( ( ret = prt_open( NULL ) ) != 0 )
return ret;
} else {
if ( ( ret = prt_open( argv[8] ) ) != 0 )
return ret;
optionen = argv[9]+2;
}
} else if ( ( ret = prt_open( NULL ) ) != 0 )
return ret;
if ( ( ret = workoptions( optionen, &offset, &w, &h, &xdpi, &ydpi, &landscape ) ) == 0 ) {
if( (long)memory==1L )
ret = drucke( (char *)0L, 0, 0, 0, 0, 0, 4, landscape, optionen ); /* Nur Ende */
else
ret = drucke( memory, offset, w, h, xdpi, ydpi, flag, landscape, optionen );
}
if( shm_name ) {
Fclose( (int)shm ); /* Shared-Memory-Datei freigeben */
shm = -1L;
Mfree( memory ); /* Speicher freigeben */
Fdelete( shm_name );
}
if ( ret ) {
Cconws( "Treiberfehler!\r\n" );
ret = -1;
} else
ret = prt_close();
return ret;
}
PAGESIZE *PAGE_getsize( long width, long height, int landscape ) {
long i, ret;
#if ( PAGEsizes < 1 )
# error "You have to define at least one PAGEsize!"
#endif
#ifndef LANDSCAPE
if ( landscape ) {
Cconws( "Dieser Treiber beherrscht kein landscape!\r\n" );
return NULL;
}
#endif
#ifndef PORTRAIT
if ( !landscape ) {
Cconws( "Dieser Treiber beherrscht kein portrait!\r\n" );
return NULL;
}
#endif
if ( width > MAXSIZE )
width = MAXSIZE;
if ( height > MAXSIZE )
height = MAXSIZE;
/* Optimalen Eintrag finden */
for ( i = 0, ret = -1; ret == -1 && i < PAGEsizes; i++ )
if ( width >= PAGEsize[i].p_minwidth &&
width <= PAGEsize[i].p_maxwidth &&
height >= PAGEsize[i].p_minheight &&
height <= PAGEsize[i].p_maxheight &&
PAGEsize[i].p_landscape == landscape )
ret = i;
/* Irgendeinen Eintrag finden */
for ( i = PAGEsizes-1; ret == -1 && i >= 0; i-- )
if ( PAGEsize[i].p_landscape == landscape )
ret = i;
/* Noteintrag verwenden */
if ( ret == -1 )
ret = PAGEsizes-1;
return PAGEsize+ret;
}
#define abs(x) ((x<0)?-x:x)
PRTVMODE *PRT_getvmode( long dpi ) {
long i, ret, rdiff, diff;
#if ( PRTvmodes < 1 )
# error "You have to define at least one PRTvmode!"
#endif
for ( ret = 0, rdiff = PRTvmode[ret].p_dpi - dpi, i = 1;
rdiff && i < PRTvmodes;
i++ ) {
diff = PRTvmode[i].p_dpi - dpi;
if ( abs(diff) < abs(rdiff) ) {
rdiff = diff;
ret = i;
} else if ( abs(diff) == abs(rdiff) && diff > 0 ) {
rdiff = diff;
ret = i;
}
}
return PRTvmode+ret;
}
PRTHMODE *PRT_gethmode( long dpi ) {
long i, ret, rdiff, diff;
#if ( PRThmodes < 1 )
# error "You have to define at least one PRThmode!"
#endif
for ( ret = 0, rdiff = PRThmode[ret].p_dpi - dpi, i = 1;
rdiff && i < PRThmodes;
i++ ) {
diff = PRThmode[i].p_dpi - dpi;
if ( abs(diff) < abs(rdiff) ) {
rdiff = diff;
ret = i;
} else if ( abs(diff) == abs(rdiff) && diff > 0 ) {
rdiff = diff;
ret = i;
}
}
return PRThmode+ret;
}
#pragma warn -par
int drucke( char *memory,
long offset, long width, long height,
long hdpi, long vdpi, int flag,
int landscape, const char *options ) {
int ret = 0;
long xoffset = 0, yoffset = 0;
PAGESIZE *pg = NULL;
PRTVMODE *pvm = NULL;
PRTHMODE *phm = NULL;
if ( landscape )
xoffset = offset;
else
yoffset = offset;
if ( xoffset + width && yoffset + height ) {
if ( ( pg = PAGE_getsize( +(1000*(xoffset+width))/hdpi, +(1000*(yoffset+height))/vdpi, landscape ) ) == NULL )
return -1;
if ( pg->p_landscape ) {
pvm = PRT_getvmode( hdpi );
phm = PRT_gethmode( vdpi );
} else {
pvm = PRT_getvmode( vdpi );
phm = PRT_gethmode( hdpi );
}
}
if ( width <= 0 && height <= 0 )
flag &= ~2;
if ( flag & 1 ) { /* Anfang? */
/* Drucker initialisieren */
prt_block( PRTinit+1, *PRTinit );
if ( pvm && pvm->p_initplus )
prt_block( pvm->p_initplus+1, *pvm->p_initplus );
if ( phm && phm->p_initplus )
prt_block( phm->p_initplus+1, *phm->p_initplus );
}
if ( flag & 2 ) { /* Daten? */
#if defined( LANDSCAPE ) && defined( PORTRAIT )
if ( pg->p_landscape )
ret = druck_landscape( memory, xoffset, yoffset, width, height, pg, phm, pvm, !(flag & 4) );
else
ret = druck_portrait( memory, xoffset, yoffset, width, height, pg, phm, pvm, !(flag & 4) );
#elif defined( LANDSCAPE )
ret = druck_landscape( memory, xoffset, yoffset, width, height, pg, phm, pvm, !(flag & 4) );
#else
ret = druck_portrait( memory, xoffset, yoffset, width, height, pg, phm, pvm, !(flag & 4) );
#endif
}
if ( flag & 4 ) { /* Ende? */
/* Drucker zurücksetzen */
if ( pvm && pvm->p_resetplus )
prt_block( pvm->p_resetplus+1, *pvm->p_resetplus );
if ( phm && phm->p_resetplus )
prt_block( phm->p_resetplus+1, *phm->p_resetplus );
prt_block( PRTreset+1, *PRTreset );
}
return ret;
}
#pragma warn -par
/*
Zusätzliche Optionen abarbeiten
<--- 0: Ok.
*/
int workoptions( const char *optionen,
long *offset, long *width, long *height,
long *hdpi, long *vdpi, int *landscape ) {
return 0;
}
#pragma warn .par
#define PIXELTOBYTE(x) x += 7; x >>= 3
#define BYTESOFPIXEL(x) ( ( x + 7 ) >> 3 )
#define PIXELTOEVENBYTE(x) x += 15; x >>= 4; x += x
#define EVENBYTESOFPIXEL(x) ( ( ( x + 15 ) >> 4 ) * 2 )
#ifdef LANDSCAPE
int druck_landscape( char *memory,
long xoffset, long yoffset,
long width, long height,
PAGESIZE *pg, PRTHMODE *phm, PRTVMODE *pvm,
boolean onlypart ) {
int ret = 0;
int p_width, p_height;
#define P_LEFT pvm->p_top
#define P_RIGHT pvm->p_bottom
#define P_TOP phm->p_right
#define P_BOTTOM phm->p_left
char *buffer;
int startvskip, starthskip, hmultiplier, vmultiplier;
int vskip;
int b, line, hrun, m, vrun, hskip, white, l;
char *srs, *dst;
boolean needlesplit = (phm->p_mode == NEEDLESPLIT);
boolean outputdone;
if ( yoffset != 0 ) {
Cconws( "Im landscape-Modus die Seiten von links nach rechts aufbauen lassen!\r\n" );
return -1;
}
/*
Vorberechnungen
*/
if ( phm->p_mode < 1 )
hmultiplier = 1;
else
hmultiplier = phm->p_mode;
if ( pvm->p_mode < 0 )
#ifdef EMUHALFPOINTBYOR
vmultiplier = (pvm->p_mode == HALFPOINT) + 1;
#else
vmultiplier = (pvm->p_mode < 0) + 1;
#endif
else if ( pvm->p_mode == 0 )
vmultiplier = 1;
else if ( pvm->p_mode > EMUMAX )
vmultiplier = EMUMAX;
else
vmultiplier = pvm->p_mode;
#if defined(NONEEDLESPLITATEMUHALFPOINT) && !defined(EMUHALFPOINTBYOR)
needlesplit &= pvm->p_mode != EMUHALFPOINT;
#endif
PIXELTOEVENBYTE( width ); /* In gerade Anzahl an Byte umrechnen */
p_width = (int)(+(pg->p_width * pvm->p_dpi) / 1000);
p_width -= P_RIGHT; /* ohne unbedruckbaren rechter Rand */
p_width -= (int)xoffset; /* ohne bereits gedruckten Teil */
PIXELTOBYTE( p_width ); /* In Anzahl Byte umrechnen */
if ( (long)p_width > width ) /* maximal den zu druckenden Teil beachten */
p_width = (int)width;
/* unbedruckbaren linken Rand entfernen */
if ( (long)P_LEFT > xoffset ) { /* beim streifenweisen drucken u.U. kein unbedruckbarer Bereich */
starthskip = P_LEFT - (int)xoffset;
PIXELTOBYTE( starthskip );
memory += starthskip;
p_width -= starthskip;
starthskip <<= 3; /* Soviele Pixelzeilen am Anfang jeweils vorfahren */
starthskip -= P_LEFT;
starthskip += (int)xoffset;
} else
starthskip = 0;
p_height = (int)(+(pg->p_height * phm->p_dpi) / 1000);
p_height -= P_BOTTOM; /* ohne unbedruckbaren unteren Rand */
if ( (long)p_height > height ) { /* maximal den zu druckenden Teil beachten */
startvskip = p_height - (int)height; /* Pixelvorschub an Anfang jeder Zeile */
p_height = (int)height;
} else
startvskip = 0;
/* unbeduckbaren oberen Rand entfernen */
memory += P_TOP * width;
p_height -= P_TOP;
p_height--; /* reine Handlingfrage */
/* unbedruckten oberen Rand entfernen */
while ( p_height >= 0 &&
prt_whitebytes( memory, p_width ) == p_width ) {
memory += width;
p_height--;
}
/* unbedruckten unteren Rand entfernen */
for ( srs = memory + p_height * width;
p_height >= 0 && prt_whitebytes( srs, p_width ) == p_width;
p_height--, srs -= width, startvskip++ );
/* unbedruckten linken Rand entfernen */
for ( srs = memory, b = (int)prt_whitebytes( srs, p_width ), line = 0;
line <= p_height && b > 0;
line++, srs += width, b =(int)prt_whitebytes( srs, b ) );
if ( b > 0 ) {
memory += b;
starthskip += b << 3;
p_width -= b;
}
/* unbedruckten rechten Rand entfernen */
for ( srs = memory+p_width-1, b = p_width, line = 0;
line <= p_height && b > 0;
line++, srs += width ) {
for ( m = 0; m < p_width && !srs[-m]; m++ );
if ( m < b )
b = m;
}
if ( b > 0 )
p_width -= b;
/* Ausgabezwischenspeicher anfordern */
if ( ( buffer = malloc( (p_height+1) * phm->p_bppl * hmultiplier ) ) == NULL ) {
Cconws( "Nicht genug Speicher für den Zeilenpuffer!\r\n" );
return -1;
}
/*
Druck-Initialisierung
*/
hskip = starthskip;
if ( pvm->p_mode > EMUNORMAL )
hskip *= vmultiplier;
/*
Hauptausgabeschleife
*/
for ( ;
p_width > 0;
memory += (pvm->p_mode < 0)? phm->p_bppl*2 : phm->p_bppl,
p_width -= (pvm->p_mode < 0)? phm->p_bppl*2 : phm->p_bppl ) {
for ( vrun = vmultiplier-1; vrun >= 0; vrun-- ) {
for ( hrun = needlesplit? 1 : 0; hrun >= 0; hrun-- ) {
vskip = startvskip;
for ( srs = memory + p_height * width, line = 0, dst = buffer;
line <= p_height;
srs -= width, line++ ) {
for ( m = hmultiplier; m > 0; m-- ) {
if ( needlesplit && (line & 1) == hrun )
for ( b = 0; b < phm->p_bppl; b++ )
*dst++ = 0;
else if ( pvm->p_mode < 0 ) {
if ( phm->p_bppl * 2 <= p_width ) {
for ( b = 0; b < phm->p_bppl*2; b += 2 )
if ( vrun )
*dst++ = (EVENBITS(srs[b]) << 4) | EVENBITS(srs[b+1]);
#ifdef EMUHALFPOINTBYOR
else if ( pvm->p_mode == EMUHALFPOINT )
*dst++ = ((EVENBITS(srs[b]) | ODDBITS(srs[b])) << 4) |
EVENBITS(srs[b+1]) | ODDBITS(srs[b+1]);
#endif
else
*dst++ = (ODDBITS(srs[b]) << 4) | ODDBITS(srs[b+1]);
} else {
for ( b = 0; b < p_width; b++ ) {
if ( b & 1 )
if ( vrun )
*dst++ |= EVENBITS(srs[b]);
#ifdef EMUHALFPOINTBYOR
else if ( pvm->p_mode == EMUHALFPOINT )
*dst++ |= EVENBITS(srs[b]) | ODDBITS(srs[b]);
#endif
else
*dst++ |= ODDBITS(srs[b]);
else if ( vrun )
*dst = EVENBITS(srs[b]) << 4;
#ifdef EMUHALFPOINTBYOR
else if ( pvm->p_mode == EMUHALFPOINT )
*dst = (EVENBITS(srs[b]) | ODDBITS(srs[b])) << 4;
#endif
else
*dst = ODDBITS(srs[b]) << 4;
}
if ( b & 1 ) {
b++;
dst++;
}
for ( ; b < phm->p_bppl*2; b += 2 )
*dst++ = '\0';
}
} else if ( vmultiplier > EMUNORMAL ) {
int n, nmp;
n = vmultiplier-vrun-1;
nmp = n * phm->p_bppl;
if ( (nmp + phm->p_bppl)/vmultiplier <= p_width ) {
for ( b = 0; b < phm->p_bppl; b++ )
*dst++ = WHICHBITS( vmultiplier, (n + b) % vmultiplier, srs[(nmp + b) / vmultiplier] );
} else {
for ( b = 0; (nmp + b)/vmultiplier < p_width; b++ )
*dst++ = WHICHBITS( vmultiplier, (n + b) % vmultiplier, srs[(nmp + b) / vmultiplier] );
for ( ; b < phm->p_bppl; b++ )
*dst++ = '\0';
}
} else if ( phm->p_bppl <= p_width ) {
for ( b = 0; b < phm->p_bppl; b++ )
*dst++ = srs[b];
} else {
for ( b = 0; b < p_width; b++ )
*dst++ = srs[b];
for ( ; b < phm->p_bppl; b++ )
*dst++ = '\0';
}
}
}
for ( srs = buffer,
line *= hmultiplier, vskip *= hmultiplier,
outputdone = false;
line > 0;
) {
white = (int)prt_whitebytes( srs, line * phm->p_bppl );
white /= phm->p_bppl;
srs += white * phm->p_bppl;
vskip += white;
line -= white;
if ( line > 0 ) {
outputdone = true;
if ( hskip > 1 || hskip == 1 && pvm->p_mode != EMUHALFPOINT ) {
b = 0;
if ( pvm->p_mode == EMUHALFPOINT ) {
b = hskip & 1;
hskip /= 2;
}
while ( hskip > 255 ) {
prt_block( pvm->p_vskip+1, pvm->p_vskip[0] );
prt_byte( 255 );
hskip -= 255;
}
if ( hskip ) {
prt_block( pvm->p_vskip+1, pvm->p_vskip[0] );
prt_byte( hskip );
}
hskip = b;
}
if ( vskip >= phm->p_relposmin ) {
b = vskip;
b *= phm->p_relposfac;
b /= phm->p_relposdiv;
if ( b ) {
prt_block( phm->p_relpos+1, phm->p_relpos[0] );
prt_byte( b );
prt_byte( b >> 8 );
b *= phm->p_relposdiv;
b /= phm->p_relposfac;
vskip -= b;
}
}
for ( l = 0;
l < line &&
prt_whitebytes( srs + l * phm->p_bppl, phm->p_relposmin * phm->p_bppl) < phm->p_relposmin * phm->p_bppl;
l++ );
prt_block( phm->p_graphic+1, phm->p_graphic[0] );
prt_byte( vskip + l );
prt_byte( (vskip + l) >> 8 );
for ( ; vskip > 0; vskip-- )
for ( b = phm->p_bppl; b > 0; b-- )
prt_byte( 0 );
prt_block( srs, l * phm->p_bppl );
line -= l;
srs += l * phm->p_bppl;
}
}
if ( outputdone ) {
#if 0
char bx[14];
const char *_itoa( int i, char *b, int r );
prt_block( phm->p_cr+1, phm->p_cr[0] );
_itoa( p_width, bx, 10 );
prt_string( bx );
#endif
prt_block( phm->p_cr+1, phm->p_cr[0] );
}
}
if ( pvm->p_mode < 0 ) {
if ( vrun & 1 ) {
if ( pvm->p_mode != EMUHALFPOINT )
hskip++;
} else {
if ( pvm->p_mode != EMUHALFPOINT ) {
if ( phm->p_bppl * 2 <= p_width )
hskip += (phm->p_bppl << 4) - 1;
else
hskip += (p_width << 3) - 1;
} else {
if ( phm->p_bppl * 2 <= p_width )
hskip += phm->p_bppl << 4;
else
hskip += p_width << 3;
}
}
} else if ( phm->p_bppl <= p_width )
hskip += phm->p_bppl << 3;
else
hskip += p_width << 3;
}
}
/*
Ende
*/
free( buffer ); /* den brauchen wir erstmal nicht mehr */
if ( onlypart && hskip > 0 ) {
if ( pvm->p_mode == EMUHALFPOINT )
hskip /= 2;
while ( hskip > 255 ) {
prt_block( pvm->p_vskip+1, pvm->p_vskip[0] );
prt_byte( 255 );
hskip -= 255;
}
if ( hskip ) {
prt_block( pvm->p_vskip+1, pvm->p_vskip[0] );
prt_byte( hskip );
}
}
return ret;
}
#endif /* LANDSCAPE */
#ifdef PORTRAIT
int druck_portrait( char *memory,
long xoffset, long yoffset,
long width, long height,
PAGESIZE *pg, PRTHMODE *phm, PRTVMODE *pvm,
boolean onlypart ) {
int ret = 0;
int p_width, p_height;
#undef P_TOP
#undef P_BOTTOM
#undef P_LEFT
#undef P_RIGHT
#define P_TOP (pvm->p_top)
#define P_BOTTOM (pvm->p_bottom)
#define P_LEFT (phm->p_left)
#define P_RIGHT (phm->p_right)
int starthskip, startvskip, hmultiplier, vmultiplier;
int startlinehskip, hskip, vskip, b, line, m, white, column, columns,
hrun, vrun, srswidth;
char *buffer, *vbuffer, *srs, *dst;
boolean outputdone;
boolean needlesplit = (phm->p_mode == NEEDLESPLIT);
if ( xoffset != 0 ) {
Cconws( "Im portrait-Modus die Seiten von oben nach unten aufbauen lassen!\r\n" );
return -1;
}
/*
Vorberechnungen
*/
hmultiplier = (phm->p_mode < 1)? 1 : phm->p_mode;
#ifdef EMUHALFPOINTBYOR
vmultiplier = (pvm->p_mode == HALFPOINT)? 2 :
#else
vmultiplier = (pvm->p_mode < 0)? 2 :
#endif
((pvm->p_mode < 1)? 1 : pvm->p_mode);
#if defined( NONEEDLESPLITATEMUHALFPOINT ) && !defined( EMUHALFPOINTBYOR )
needlesplit &= (pvm->p_mode != EMUHALFPOINT);
#endif
PIXELTOEVENBYTE( width );
p_width = (int)(+(pg->p_width * phm->p_dpi) / 1000);
p_width -= P_RIGHT; /* ohne unbedruckbaren rechter Rand */
PIXELTOBYTE( p_width ); /* In Anzahl Byte umrechnen */
if ( (long)p_width > width ) /* maximal den zu druckenden Teil beachten */
p_width = (int)width;
/* unbedruckbaren linken Rand entfernen */
if ( P_LEFT > 0 ) {
starthskip = P_LEFT;
PIXELTOBYTE( starthskip );
memory += starthskip;
p_width -= starthskip;
starthskip <<= 3; /* Soviele Pixelzeilen am Anfang jeweils vorfahren */
starthskip -= P_LEFT;
} else
starthskip = 0;
p_height = (int)(+(pg->p_height * phm->p_dpi) / 1000);
p_height -= P_BOTTOM; /* ohne unbedruckbaren unteren Rand */
if ( (long)p_height > height ) /* maximal den zu druckenden Teil beachten */
p_height = (int)height;
/* unbeduckbaren oberen Rand entfernen */
if ( P_TOP > yoffset ) {
memory += (P_TOP - yoffset) * width;
p_height -= (P_TOP - (int)yoffset);
}
startvskip = 0;
p_height--; /* reine Handlingfrage */
/* unbedruckten oberen Rand entfernen */
while ( p_height >= 0 &&
prt_whitebytes( memory, p_width ) == p_width ) {
memory += width;
p_height--;
startvskip++;
}
/* unbedruckten unteren Rand entfernen */
for ( srs = memory + p_height * width;
p_height >= 0 && prt_whitebytes( srs, p_width ) == p_width;
p_height--, srs -= width );
/* unbedruckten linken Rand entfernen */
for ( srs = memory, b = (int)prt_whitebytes( srs, p_width ), line = 0;
line < p_height && b > 0;
line++, srs += width, b =(int)prt_whitebytes( srs, b ) );
if ( b > 0 ) {
memory += b;
starthskip += b << 3;
p_width -= b;
}
/* unbedruckten rechten Rand entfernen */
for ( srs = memory+p_width-1, b = p_width, line = 0;
line < p_height && b > 0;
line++, srs += width ) {
for ( m = 0; m < p_width && !srs[-m]; m++ );
if ( m < b )
b = m;
}
if ( b > 0 )
p_width -= b;
/* Ausgabezwischenspeicher anfordern */
if ( ( buffer = malloc( (long)(p_width * phm->p_bppl) << 3 ) ) == NULL ) {
Cconws( "Nicht genug Speicher für den Zeilenpuffer!\r\n" );
return -1;
}
if ( vmultiplier > 1 &&
( vbuffer = malloc( (long)(width * phm->p_bppl) << 3 ) ) == NULL ) {
Cconws( "Nicht genug Speicher für Zeilenzwischenpuffer!\r\n" );
return -1;
}
/*
Druck-Initialisierung
*/
vskip = startvskip;
if ( pvm->p_mode > 1 )
vskip *= pvm->p_mode;
/*
Hauptschleife
*/
for ( ;
p_height >= 0;
p_height -= phm->p_bppl << ((pvm->p_mode < 0)? 4 : 3),
memory += width * (phm->p_bppl << ((pvm->p_mode < 0)? 4 : 3)) ) {
/* weiße Zeilen überspringen */
for ( ;
p_height >= 0 &&
prt_whitebytes( memory, p_width ) == p_width;
p_height--, memory += width, vskip += ((pvm->p_mode > 1)? pvm->p_mode : 1) );
startlinehskip = starthskip;
if ( vmultiplier == 1 )
vbuffer = memory;
#ifdef EMUHALFPOINTBYOR
for ( vrun = pvm->p_mode == EMUHALFPOINT,
#else
for ( vrun = 0,
#endif
line = 0;
vrun < vmultiplier;
vrun++ ) {
if ( vmultiplier > 1 )
if ( pvm->p_mode == HALFPOINT
#ifndef EMUHALFPOINTBYOR
|| pvm->p_mode == EMUHALFPOINT
#endif
)
for ( srs = memory + vrun * width,
dst = vbuffer, b = vrun;
b < (phm->p_bppl << 4);
srs += width*2, dst += width, b += 2 )
if ( b <= p_height )
memcpy( dst, srs, p_width );
else
memset( dst, 0, p_width );
#ifdef EMUHALFPOINTBYOR
else if ( pvm->p_mode == EMUHALFPOINT )
for ( srs = memory, dst = vbuffer, b = 0;
b < (phm->p_bppl << 4);
srs += width, b++ )
if ( b & 1 ) {
if ( b <= p_height )
memor( dst, srs, p_width );
dst += width;
} else if ( b <= p_height )
memcpy( dst, srs, p_width );
else
memset( dst, 0, p_width );
#endif
else
for ( srs = memory + (line / vmultiplier - 1) * width,
dst = vbuffer, b = 0;
b < (phm->p_bppl << 3);
dst += width, b++, line++ ) {
if ( !(line % vmultiplier) )
srs += width;
if ( line / vmultiplier <= p_height )
memcpy( dst, srs, p_width );
else {
b = (phm->p_bppl << 3) - b;
line += b-1;
memset( dst, 0, b*width );
b = (phm->p_bppl << 3)-1;
}
}
if ( p_height >= 0 ) {
if ( pvm->p_mode > 1 && (p_height+1)*pvm->p_mode < (phm->p_bppl << 3) )
prt_prtcpysome( buffer, vbuffer,
(int)width, p_width,
phm->p_bppl, (p_height+1)*pvm->p_mode );
else if ( pvm->p_mode <= 1 && p_height+1 < (phm->p_bppl << 3) )
prt_prtcpysome( buffer, vbuffer,
(int)width, p_width,
phm->p_bppl, p_height+1 );
else
prt_prtcpy( buffer, vbuffer,
(int)width, p_width,
phm->p_bppl );
for ( hrun = (needlesplit != false); hrun >= 0; hrun-- ) {
hskip = startlinehskip;
/* Optimierungsschleife */
for ( srs = buffer, srswidth = (p_width << 3) * phm->p_bppl;
srswidth > 0 &&
(white = (int)prt_whitebytes( srs, srswidth )) < srswidth;
columns *= phm->p_bppl, srs += columns,
srswidth -= columns ) {
white /= phm->p_bppl;
hskip += white;
white *= phm->p_bppl;
srs += white;
srswidth -= white;
/* Zuerst der vertikale Vorschub */
if ( vskip > 0 ) {
if ( pvm->p_mode == EMUHALFPOINT ) {
b = vskip & 1;
vskip /= 2;
}
while ( vskip > 255 ) {
prt_block( pvm->p_vskip+1, pvm->p_vskip[0] );
prt_byte( 255 );
vskip -= 255;
}
if ( vskip > 0 ) {
prt_block( pvm->p_vskip+1, pvm->p_vskip[0] );
prt_byte( vskip );
vskip = 0;
}
if ( pvm->p_mode == EMUHALFPOINT )
vskip = b;
}
/* Jetzt der horizontale Vorschub */
if ( hskip > phm->p_relposmin ) {
b = hskip;
b *= phm->p_relposfac;
b /= phm->p_relposdiv;
prt_block( phm->p_relpos+1, phm->p_relpos[0] );
prt_byte( b );
prt_byte( b >> 8 );
b *= phm->p_relposdiv;
b /= phm->p_relposfac;
hskip -= b;
}
for ( columns = 0;
columns < srswidth &&
prt_whitebytes( srs+columns, phm->p_bppl*phm->p_relposmin ) != phm->p_bppl*phm->p_relposmin;
columns += phm->p_bppl );
columns /= phm->p_bppl;
prt_block( phm->p_graphic+1, phm->p_graphic[0] );
prt_byte( (hskip + columns) * hmultiplier );
prt_byte( ((hskip + columns) * hmultiplier ) >> 8 );
for ( ; hskip > 0; hskip-- )
for ( b = phm->p_bppl * hmultiplier; b > 0; b-- )
prt_byte( 0 );
if ( needlesplit ) {
for ( dst = srs, column = columns;
column > 0;
dst += phm->p_bppl, column-- )
if ( (column & 1) == hrun )
for ( b = 0; b < phm->p_bppl; b++ )
prt_byte( 0 );
else
prt_block( dst, phm->p_bppl );
} else if ( hmultiplier > 1 ) {
for ( dst = srs, column = columns;
column > 0;
dst += phm->p_bppl, column-- )
for ( hrun = 0; hrun < hmultiplier; hrun++ )
prt_block( dst, phm->p_bppl );
} else
prt_block( srs, columns * phm->p_bppl );
outputdone = true;
}
if ( outputdone )
prt_block( phm->p_cr+1, phm->p_cr[0] );
}
if ( pvm->p_mode < 0 )
if ( !vrun )
vskip++;
else if ( (p_height+1) < (phm->p_bppl << 4) - 1 )
vskip += p_height;
else
vskip += (phm->p_bppl << 4) - 1;
else if ( pvm->p_mode > 1 && (p_height+1)*pvm->p_mode < (phm->p_bppl << 3) )
vskip += (p_height+1) * pvm->p_mode;
else if ( pvm->p_mode <= 1 && (p_height+1) < (phm->p_bppl << 3) )
vskip += p_height + 1;
else
vskip += phm->p_bppl << 3;
}
}
}
/*
Ende
*/
if ( vskip > 0 ) {
if ( onlypart ) {
if ( pvm->p_mode == EMUHALFPOINT ) {
b = vskip & 1;
vskip /= 2;
}
while ( vskip > 255 ) {
prt_block( pvm->p_vskip+1, pvm->p_vskip[0] );
prt_byte( 255 );
vskip -= 255;
}
if ( vskip > 0 ) {
prt_block( pvm->p_vskip+1, pvm->p_vskip[0] );
prt_byte( vskip );
vskip = 0;
}
if ( pvm->p_mode == EMUHALFPOINT )
vskip = b;
}
}
return ret;
}
#endif /* PORTRAIT */
#endif /* NADEL_C */